/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Project2.cs342.project1.mathNotebook.Database;

import java.math.BigInteger;
import java.sql.*;
import java.io.*;
import java.security.interfaces.RSAPublicKey;
import java.util.*;
/**
 *
 * @author Rick
 */
public class DBUsers {
    static String id = null;
    static String file_name = null;
    static Connection conn = null;
    PreparedStatement ps = null;
    SQLConfigeration sqlConfig;

    public DBUsers(){
        sqlConfig = new SQLConfigeration();
        conn = sqlConfig.getConnection();
    }

    /**
     * inserts the provided fields into the user table
     *
     * @param userName the name of the user
     * @param localPublicKey a byte array of the users public rsa key to be placed in a blob
     * @param localPrivateKey a byte array of the users private rsa key to be place in a blob
     * @param localDES the users des key in the form of a BigInt
     * @return success or unsuccess
     */
    public boolean insertIntoUsers(String userName, String password){

        boolean insertSuccess = false;
        //Insert data
        String groupAccess = "insert into Users(username, localPublicKey," +
                                                "localPrivateKey, localDES, password) " +
                                                    "values (?,?,?,?,?)";
        FileInputStream fis = null;

        try{
            conn.setAutoCommit(false);
            File filePublicKey = new File("public.txt");
            File filePrivateKey = new File("private.txt");
            File fileLocalDES = new File("localDes.txt");

            ps = conn.prepareStatement(groupAccess);

            ps.setString(1, userName);
            fis = new FileInputStream(filePublicKey);
            ps.setBinaryStream(2,fis, (int)filePublicKey.length());
            fis = new FileInputStream(filePrivateKey);
            ps.setBinaryStream(3, fis, (int)filePrivateKey.length());
            fis = new FileInputStream(fileLocalDES);
            ps.setBinaryStream(4, fis, (int)fileLocalDES.length());
            ps.setString(5, password);
            System.out.println("Attempting insert");
            ps.executeUpdate();
            conn.commit();
            System.out.println("Insert successful");
            insertSuccess = true;

        }catch(SQLException ex){
            System.out.println("Insert unsuccessful");
            insertSuccess = false;
        }catch(Exception ex){
            System.out.println("Insert Error " + ex + " at:");
            ex.printStackTrace();
        }finally{
            try {
                ps.close();

            } catch (SQLException ex) {
                System.out.println("Sql Error " + ex);
            }
        }
        return insertSuccess;
    }

    /**
     * Determines if user exits
     *
     * @param username name of user to search for
     * @return boolean value if user exits
     */
    public boolean doesUserExist(String username){
        boolean userExists = false;
        String nameOfUser = null;

        ResultSet rs = null;
        PreparedStatement pstmt = null;
        String query = "Select username from Users where username = ?";

        try{
            pstmt = conn.prepareStatement(query);

            pstmt.setString(1, username);
            rs = pstmt.executeQuery();

            rs.next();

            System.out.println("Attempting to see if user exists");

            nameOfUser = rs.getString("username");

            System.out.println("User Found");
            userExists = true;

        }catch(Exception ex)
        {
            System.out.println("User not Found");
            userExists = false;
            //ex.printStackTrace();
        }
        finally{
            try {
                rs.close();
                pstmt.close();
                //conn.close();
            } catch (SQLException ex) {
                System.out.println("SQL Error: " + ex);
            } catch (Exception ex) {
               
            }
	    
        }


        return userExists;
    }

    /**
     * user to see if username and password are correct for login
     *
     * @param username
     * @param password
     * @return login success or failier
     */
    public boolean checkLogin(String username, String password){
        boolean matchFound = false;
        String usersPassword;

        ResultSet rs = null;
        PreparedStatement pstmt = null;
        String query = "Select username, password from Users where username = ? and password = ?";

        try{
            pstmt = conn.prepareStatement(query);

            pstmt.setString(1, username);
            pstmt.setString(2, password);
            rs = pstmt.executeQuery();

            rs.next();
            System.out.println("Query: " + query);
            System.out.println("Attempting to check users password");

            usersPassword = rs.getString("username");

            System.out.println("Login Success");
            matchFound = true;


        }catch(Exception ex)
        {
            System.out.println("Login unsuccessful");
            matchFound = false;
            //ex.printStackTrace();
        }
        finally{
            try {
                rs.close();
                pstmt.close();
                //conn.close();
            } catch (SQLException ex) {
                System.out.println("SQL Error: " + ex);
            }
	    catch(Exception ex){
	    }
        }

        return matchFound;
    }

    /**
     * retrieves the rsa public key for a user
     *
     * @param username the user who's public key we are asking for
     * @return the rsa public key in the form of a byte array
     */
    public void retrieveRSAPublicKey(String username){
        ResultSet rs = null;
        PreparedStatement pstmt = null;
        String query = "Select localPublicKey from Users where username = ?";
        Blob blob = null;

        try{
            pstmt = conn.prepareStatement(query);

            pstmt.setString(1, username);
            rs = pstmt.executeQuery();

            rs.next();

            //get the binary blob data onto the client
            System.out.println("Attempting to get the blob");
            blob = rs.getBlob(1);
            System.out.println("Blob recieved of length " + blob.length());

        }catch(Exception ex){System.out.println("Retrieval Error: " + ex);}
        finally{
            try {
                rs.close();
                pstmt.close();
                //conn.close();
            } catch (SQLException ex) {
                System.out.println("SQL Error: " + ex);
            }

        }

        //writing out the recieved blob
        try{
            FileOutputStream out = new FileOutputStream("public.txt");
            BufferedInputStream in = new BufferedInputStream(blob.getBinaryStream());

            int b;
            byte[] buffer = new byte[10240];
            try{
                while((b = in.read(buffer, 0, 10240)) != -1){
                    out.write(buffer, 0, b);
                }
                out.close();
            }catch(IOException ex){
                System.out.println("File Output Error: " + ex);
            }

        }catch(FileNotFoundException ex){
            System.out.println("Error: " + ex);
        }catch(SQLException ex){
            System.out.println("SQL Error: " + ex);
        }
    }

    /**
     * retrieves the rsa private key for a user
     *
     * @param username the user who's private key we are asking for
     * @return the rsa private key in the form of a byte array
     */
    public void retrieveRSAPrivateKey(String username){
        ResultSet rs = null;
        PreparedStatement pstmt = null;
        String query = "Select localPrivateKey from Users where username = ?";
        Blob blob = null;

        try{
            pstmt = conn.prepareStatement(query);

            pstmt.setString(1, username);
            rs = pstmt.executeQuery();

            rs.next();

            //get the binary blob data onto the client
            System.out.println("Attempting to get the blob");
            blob = rs.getBlob(1);
            System.out.println("Blob recieved of length " + blob.length());

        }catch(Exception ex){System.out.println("Retrieval Error: " + ex);}
        finally{
            try {
                rs.close();
                pstmt.close();
                //conn.close();
            } catch (SQLException ex) {
                System.out.println("SQL Error: " + ex);
            }

        }

        //writing out the recieved blob
        try{
            FileOutputStream out = new FileOutputStream("private.txt");
            BufferedInputStream in = new BufferedInputStream(blob.getBinaryStream());

            int b;
            byte[] buffer = new byte[10240];
            try{
                while((b = in.read(buffer, 0, 10240)) != -1){
                    out.write(buffer, 0, b);
                }
                out.close();
            }catch(IOException ex){
                System.out.println("File Output Error: " + ex);
            }

        }catch(FileNotFoundException ex){
            System.out.println("Error: " + ex);
        }catch(SQLException ex){
            System.out.println("SQL Error: " + ex);
        }
    }

    /**
     * retrieve the local des key in the form of a String
     *
     * @param userName the user associated with this desKey
     * @return a String representing the desKey
     */
    public void retrieveDESKey(String userName){

        String desKey = null;
        ResultSet rs = null;
        PreparedStatement pstmt = null;
        String query = "Select localDes from Users where username = ?";
        Blob blob = null;

        try{
            pstmt = conn.prepareStatement(query);

            pstmt.setString(1, userName);
            rs = pstmt.executeQuery();

            rs.next();

            //get the binary blob data onto the client
            System.out.println("Attempting to get the blob");
            blob = rs.getBlob(1);
            System.out.println("Blob recieved of length " + blob.length());

        }catch(Exception ex){System.out.println("Retrieval Error: " + ex);}
        finally{
            try {
                rs.close();
                pstmt.close();
                //conn.close();
            } catch (SQLException ex) {
                System.out.println("SQL Error: " + ex);
            }

        }

        //writing out the recieved blob
        try{
            FileOutputStream out = new FileOutputStream("localDes.txt");
            BufferedInputStream in = new BufferedInputStream(blob.getBinaryStream());

            int b;
            byte[] buffer = new byte[10240];
            try{
                while((b = in.read(buffer, 0, 10240)) != -1){
                    out.write(buffer, 0, b);
                }
                out.close();
            }catch(IOException ex){
                System.out.println("File Output Error: " + ex);
            }

        }catch(FileNotFoundException ex){
            System.out.println("Error: " + ex);
        }catch(SQLException ex){
            System.out.println("SQL Error: " + ex);
        }
    }

    /**
     * Deletes the provided user from the table
     *
     * @param username the user to be deleted
     * @return success or unsuccess
     */
    public boolean deleteRowFromUsers(String username){
        boolean removalSuccess = false;
        String deleteGroupMember = "delete from Users where username = '" + username + "'";
        try{
            conn.setAutoCommit(false);
            ps = conn.prepareStatement(deleteGroupMember);
            System.out.println("Attempting Deletion");
            ps.executeUpdate();
            conn.commit();
            System.out.println("Delection Successful");
            removalSuccess = true;

        }catch(SQLException ex){
            System.out.println("Deletion Error: " + ex);
            removalSuccess = false;
        }
        return removalSuccess;
    }
    public String[] retrieveAllOtherUsers(String groupNotIn){
        String[] users = new String[50];
        ResultSet rs = null;
        PreparedStatement pstmt = null;
        String query = "Select username from Users";

        try{
            pstmt = conn.prepareStatement(query);

            //pstmt.setString(1, groupNotIn);
            rs = pstmt.executeQuery();

            //get the binary blob data onto the client
            System.out.println("Attempting to Users in group");
            int index = 0;
            while(rs.next()){
                users[index] = rs.getString("username");
                //System.out.println("Recieved: " + filename[index]);
                index++;
            }

        }catch(Exception ex){System.out.println("Retrieval Error: " + ex);}
        finally{
            try {
                rs.close();
                pstmt.close();
                //conn.close();
            } catch (SQLException ex) {
                System.out.println("SQL Error: " + ex);
            }
        }
        ArrayList<String> list = new ArrayList<String>();
        for (int i = 0; i < users.length;i++){
            if (users[i]!=null){
                list.add(users[i]);
                System.out.println(users[i] + " in the Group");
            }
        }
        String[] users2 = new String[list.size()];
        list.toArray(users2);
        return users2;
    }
}
